﻿// -----------------------------------------------------------------------
// <copyright file="TouchDirectory.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace TouchExplorer
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
using System.Windows.Media.Imaging;
    using System.Windows.Threading;
    using System.ComponentModel;
    using Microsoft.WindowsAPICodePack.Shell;
    using System.Windows;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class TouchDirectory : TouchFileElementBase
    {
        public DirectoryInfo Info { get; private set; }

        public string FullName { get; protected set; }

        public TouchDirectory(DirectoryInfo dir)
        {
            Info = dir;
            FullPath = dir.FullName;
            if (FullPath != dir.Name)
                FullName = FullPath;
            Name = dir.Name;
            //Image = _defaultImage;
        }

        public TouchDirectory(ShellObject folder)
        {
            Shell = folder;
            FullPath = folder.ParsingName;            
                    
            try
            {
                if (!string.IsNullOrEmpty(folder.ParsingName) && Directory.Exists(folder.ParsingName))
                {
                    Info = new DirectoryInfo(FullPath);
                }
                Name = folder.Name;                
            }
            catch (Exception ex)
            {
                var msg = ex.ToString();
            }

            if (Info == null)
            {
                try
                {
                    if (!string.IsNullOrEmpty(FullPath))
                    {
                        Info = new DirectoryInfo(FullPath);
                    }                    
                }
                catch (Exception)
                {
                }
            }
            
            if (string.IsNullOrEmpty(Name) && Info != null) 
                Name = Info.Name;

            if (string.IsNullOrEmpty(Name))
                Name = Path.GetDirectoryName(FullPath);
        }

        ~TouchDirectory()
        {
            Shell = null;
            Info = null;
            BigImage = null;
            Image = null;
        }

        public IEnumerable<TouchFile> GetFiles(Func<TouchFile, bool> filter=null)
        {
            try
            {
                return DoGetFiles(filter);
            }
            catch (Exception)
            {
                return new List<TouchFile>();   
            }
        }

        private IEnumerable<TouchFile> DoGetFiles(Func<TouchFile, bool> filter)
        {
            var res = new List<TouchFile>();

            if (Shell != null)
            {
                lock (Shell)
                {
                    foreach (ShellObject shellObj in (Shell as ShellContainer))
                    {
                        if (File.Exists(shellObj.ParsingName))
                        {
                            var file = GetFile(shellObj.ParsingName, shellObj);
                            res.Add(file);
                        }
                    }
                }

            }
            else if (!string.IsNullOrEmpty(FullPath) && Directory.Exists(FullPath))
            {
                var files = Directory.GetFiles(FullPath);

                var lst = files.Select(f => GetFile(f));
                if (filter != null) 
                    lst = lst.Where(filter);

                return lst;
            }
            

            if (filter != null)
                return res.Where(filter);

            return res;
        }

        public IEnumerable<TouchDirectory> GetDirectories(Func<TouchDirectory, bool> filter=null)
        {
            try
            {
               return this.DoGetDirectories(filter);
            }
            catch (Exception)
            {
                MessageBox.Show("Bad luck, you cannot access this folder content...");
                return new List<TouchDirectory>();
            }
        }

        private IEnumerable<TouchDirectory> DoGetDirectories(Func<TouchDirectory, bool> filter)
        {
            if (Shell != null && Info == null)
            {
                return this.GetChildShellDirectories(filter);
            }
            if (Info == null && Shell == null)
            {
                return GetChildDirectories();
            }
            //TODO, manage access denied
            

            var lst = Info.GetDirectories().Select(d => new TouchDirectory(d));
            
            if (filter != null)
                lst = lst.Where(filter);
            
            return lst;
        }

        private static IEnumerable<TouchDirectory> GetChildDirectories()
        {
            var res = System.IO.DriveInfo.GetDrives();
            return res.Select(r => GetDirectory(r.RootDirectory.FullName));
        }

        private IEnumerable<TouchDirectory> GetChildShellDirectories(Func<TouchDirectory, bool> filter)
        {
            lock (this.Shell)
            {
                var res = new List<TouchDirectory>();
                foreach (ShellObject obj in (this.Shell as ShellContainer))
                {
                    if (!File.Exists(obj.ParsingName))
                    {
                        var elt = GetDirectory(obj.ParsingName, obj);

                        res.Add(elt);
                    }
                }

                if (filter != null)
                {
                    return res.Where(filter);
                }

                return res;
            }
        }

        private static TouchDirectory GetDirectory(string path, ShellObject shell = null)
        {
            TouchDirectory elt = null;
            if (App.Current.Clipboard.Has(path))
            {
                elt = (TouchDirectory)App.Current.Clipboard[path];
            }
            else
            {
                if (shell != null)
                    elt = new TouchDirectory(shell);
                else
                    elt = new TouchDirectory(new DirectoryInfo(path));
            }

            elt.IsFavorite = App.Current.Favorites.Has(elt);

            return elt;
        }

        private static TouchFile GetFile(string path, ShellObject shell = null)
        {
            TouchFile elt = null;
            if (App.Current.Clipboard.Has(path))
            {
                elt = (TouchFile)App.Current.Clipboard[path];
            }
            else
            {
                if (shell != null)
                    elt = new TouchFile(shell);
                else
                    elt = new TouchFile(new FileInfo(path));
            }

            elt.IsFavorite = App.Current.Favorites.Has(elt);

            return elt;
        }

        public override bool Exists
        {
            get
            {
                if (string.IsNullOrEmpty(FullPath)) return false;

                return Directory.Exists(FullPath);
            }
        }
    }
}
